前Facebook面试官告诉你如何才能顺利通过编程面试
许多应聘者往往在简单的小事上遭遇滑铁卢,比如主观的假设,没有传达自己的想法,编写的测试用例不佳等等。本文将重点介绍作者在Facebook担任软件工程面试官期间所学到的经验教训。
以下为译文:
去年,我花了无数的时间来面试应聘Facebook的工程师。
作为一名同时拥有面试者和面试官双方经验的人,我想通过本文为大家提供一些帮助。
也许你是一名大学生,正在寻找第一次软件工程的实习机会。也许你已然是一名软件工程师,但你希望跳槽到一家新公司。
或者上面两种情况都不适合你,你从业于其他行业,但希望尝试闯入软件工程的世界。
本文将重点介绍我在Facebook担任软件工程面试官期间所学到的经验教训。
我希望对面试感到迷茫的人们能有所启发。
编程面试的常见形式是长达45分钟的对话,目的是检验你对数据结构和算法的掌握。
大多数公司的实习生应聘者只需要通过编程面试。但是,高级应聘者可能需要经历2-3次编程面试,1-2次系统设计面试以及一次行为面试。
本文只介绍有关编程面试的建议。
最近有人问我:“如果遇到没见过的问题,该怎么办?”
那么我的答案是:“如果是一个精心构思的面试问题,那么你肯定没见过。”
如果你知道面试题的答案,那么面试又有何意义呢?编程面试的目的就是检验你的编程技术力。在Facebook,我们管这个叫做“信号”。
作为面试官,我们的目标是尽可能地获取更多的信号。因此,如果我们发现你听说过我们的题目,那么我们肯定会换题。
我们想了解你在逆境中的表现。
如果恰巧你在“攻克编程面试”的练习题中见过解决方案,那么我们将无法了解你解决问题的能力。
优秀的应聘者必然会从面试中脱颖而出。他们几乎不需要面试官的指导。他们才是面试的主导,而不是面试官。
通常,这些应聘者会自主完成如下这些步骤,面试官几乎不需要给予任何提示:
澄清问题;
分析各种解决方案以及权衡利弊;
使用伪代码计划解决方案;
实现解决方案;
测试。
主导编程面试并不意味着在拿到题目后着急写代码。实际上,在面试的前五分钟内开始编写代码通常是一个非常糟糕的信号。
如果想在面试中有出色的表现,则第一步应该通过提问澄清问题。
通过提问澄清问题
在开始解决问题之前,你需要清楚地理解问题。
有关澄清问题的提问可以为你的成功奠定良好的基础。
如下是一些很好的提问:
是否应该原地进行操作?(不适用额外的内存)
我们可以对输入进行任何假设吗?
我们是否需要考虑性能或节省内存?
在弄清楚这些问题后,你就可以专心解决重要的问题,同时忽略其余细枝末节了。知道应该忽略什么与知道应该关注什么同等重要。
面试者往往会对问题做出一些假设,例如所有整数都是正数,数组不为空,所有输入都是安全的等等,这些都是红色警告。
切忌为了方便解决问题而做一些假设条件。你应该主动提问。
“传递给这个问题的整数是否都是正数?”
如此一个简单的提问即可。如果是,那肯定很好,你不需要额外的检查。如果不是,那么你只需通过一个简单的if语句确保代码的安全。
通常,这样的提问可以为你前进的方向提供重要提示。
面试官喜欢看到应聘者讨论各种解决问题的方法。
这种讨论表明你明白解决问题的方法有很多种,更重要的是,即便你没有明确要求,面试官可能也会给出提示。
虽然我们不能直接给出正确答案,但是如果你提出两个选择,A和B,然后问:“你认为我应该采用哪种方法?”那么我们肯定愿意选择最接近答案的方法。
通常,你需要在白板上完成编程面试。这意味着你无法随意修改你的代码。在编写代码之前,你必须清楚地了解自己的解决方案。
你需要认真思考,并计划好代码。你可以通过伪代码,也可以绘制简单的图形,但是请确保你知道你将要使用什么数据结构,以及需要跟踪什么变量。
你肯定不希望自己最终提供的解决方案像下面这样:
这是每个人都很担心的一步,实际则不然。
实现解决方案应该是最简单的一步。因为你已经通过提问澄清了问题,考虑了各种不同的解决方案,同时还计划好了算法,现在只需写出代码即可。
但是在实现的过程中,切记:
大声交流。如果我不知道你在想什么,那么就很难指引你找到正确的方向。
如果你的方向错了,那么我可以介入。如果你的方向正确,那么我应该什么也不说,让你继续前进。
小贴士:不同的面试官有不同的风格。有些面试官会更加积极主动地介入。
由于某些原因,人们往往最有可能忽略这一步。我想说,在我面试过的人中,如果他们能编写良好的测试,那么98%的人能获得更高的分数。
在面试开始时,应聘者通常都会接到一个面试题和一个简单的测试用例。
在应聘者编写完解决方案后,他们都会运行我们给出的测试用例。但唯一的问题在于,我们只为你提供了最简单的测试用例,其不包含边缘案例,也不具备正确测试代码的能力。
如果你的算法只能针对该测试用例提供正确的输出,那么并不能保证这个算法可以在各种情况下都提供正确的输出。
在编程面试中脱颖而出的最简单方法就是——编写更多测试,编写更难的测试,编写更全面的测试。
通常,即便我不介入,你也可以通过这种方法捕捉到很多bug。这可以为你的表现加分。
如果面试官问到一个你不知道该如何解决的问题时,你该怎么办?
一步步来,循序渐进。
回想一下,这个问题是否与你以前见过的某个问题类似。我提出的许多编程问题其实都是基本的算法问题,大多数数据结构和算法课程中都讲过,只不过我的问题略有所改动。
如果你大脑一片空白,那也不要惊慌。这完全正常。
不要不知所措,急于提出最有效的解决方案。你可以从最简单的解决方案开始。
然后从这个解决方案开始,思考瓶颈在哪里?算法的哪个方面的效率有待提高?你可以采取哪些措施来最大程度地提高效率?
在尝试提高算法效率时,有时可以利用数据结构的优势(尽管有时也未必可行)。
每种数据结构都有优点和缺点,例如哈希表的查找速度,BST的排序等等。
当你利用特定的数据结构来解决问题的瓶颈时,就会发现问题的最佳解决方案。
例如:
针对给定的一个句子,返回字母表中每个字母的出现次数。
如果用蛮力解决这个问题,那么只能一次统计一个字母的出现次数,然后输出结果。这里的瓶颈在于存储/查找信息。我们需要将句子中每个字母的出现次数存储起来,然后在最后查找最终结果。
下面我们来看看备选的数据结构,然后挑出最有利的那个:
二叉搜索树;
数组;
哈希图;
平衡二叉树;
栈;
队列。
显然,能够最有效地存储和检索数据的数据结构是哈希表。
因此,如果我们利用哈希表来解决这个问题,那么就无需重复执行语句26次。只需运行一次足矣。
通常面试题都有窍门,如果你能找到就可以更有效地解决问题。
有些问题巧妙地描述了某个独特的条件,你可以利用这个条件更高效地完成任务。因此,你需要找到这样的窍门。
举个例子说明:
有两个排序的整数数组A和B,将B合并到A,输出一个排序的数组;
你可以会假设A有足够的空间来保存来自B的元素。最初,A和B的元素数分别为m和n。
这个问题就来自《攻克编程面试》这本书的练习题。
你发现这里的窍门了吗?
这道题本来也可以说成:将两个排序的数组合并起来,但是我们并没有这么说。
我们给出了两个数组,其中一个可以完整地嵌入到另一个中。
这就是我所说的窍门。如果你看到类似的描述时,就应该注意到这样说肯定有原因。
由于数组A有足够的空位嵌入数组B,所以你可以更有效地解决这个问题。
点击这里获取完整的解决方案(https://www.programcreek.com/2012/12/leetcode-merge-sorted-array-java/)。
有时即便你完成了这些步骤,仍然不清楚具体的解决方案。在这种情况下,你只能寻求帮助。
与面试官沉默相对十分钟,对我们两个人都没有好处。如果你真的不知道该怎么办,那么就应该寻求提示。
每个人都会有需要提示的时候。而关键在于你如何利用面试官给予的提示。
技术面试也是一项标准化考试,如同ACT、SAT、GRE等等一样。尽管各个问题的细节可能有所不同,但解决问题所涉及的主要概念和策略已经标准化。
许多应聘者往往在简单的小事上遭遇滑铁卢,比如主观的假设,没有传达自己的想法,编写的测试用例不佳等等。
希望通过阅读本文,每位应聘者都可以纠正这些错误,并拿下自己心仪的工作。
原文:https://medium.com/better-programming/how-to-ace-the-coding-interview-by-an-ex-facebook-interviewer-9c163a845d05
作者:Ish Baid,Virtually的创始人,前Facebook工程师。
本文为 CSDN 翻译,转载请注明来源出处。
热 文 推 荐
☞三年一跳槽、拒绝“唯学历”,火速 Get 这份程序员求生指南!
☞“国家队”入局! 中移动、银联等宣布区块链服务网络(BSN)正式内测!